﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LGPeWJNM.BaseClasses;

namespace PrvcGlp
{
    public partial class Form1 : Form
    {
        LGPeWJNM.DataAccessLayer.Instancia instancia;
        System.Threading.Thread thread;
        double _totalOtimo = double.MaxValue;

        public IEnumerable<LinkedList<LGPeWJNM.BaseClasses.ICliente>> otimo { get; set; }
        public double totalOtimo
        {
            get { return _totalOtimo; }
            set
            {
                this._totalOtimo = value;
                this.BeginInvoke(new MethodInvoker(() => { this.textBox1.Text = value.ToString(); }));
            }
        }
        public Form1()
        {
            InitializeComponent();
            this.thread = new System.Threading.Thread(new System.Threading.ThreadStart(this.ProcessRoute));
        }

        private void carregarDadosToolStripMenuItem_Click(object sender, EventArgs e)
        {
            switch (openFileDialog1.ShowDialog())
            {
                case DialogResult.OK:
                case DialogResult.Yes:
                    instancia = new LGPeWJNM.DataAccessLayer.InstanciaCsv(openFileDialog1.FileName);
                    break;
            }
            instancia.QuantidadeVeiculos = Properties.Settings.Default.QuantidadeDeVeiculos;
            instancia.CapacidadeVeiculo = Properties.Settings.Default.CapacidadeVeiculo;
            instancia.Deposito = new LGPeWJNM.BaseClasses.Point()
            {
                X = double.Parse(Properties.Settings.Default.LongitudeDeposito),
                Y = double.Parse(Properties.Settings.Default.LatitudeDeposito)
            };
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (!this.thread.IsAlive)
            {
                this.thread.Start();
                this.button1.Text = "Parar";
            }
            else
            {
                this.thread.Abort();
                this.thread = new System.Threading.Thread(new System.Threading.ThreadStart(this.ProcessRoute));
                this.button1.Text = "Iniciar";
            }
        }

        private void ProcessRoute()
        {
            var mc = new LGPeWJNM.MonteCarlo.MonteCarlo();
            var gj = new LGPeWJNM.GilletJohnson.GilletJohnson();
            var vmp = new LGPeWJNM.Vmp.Vmp();
            var opt = new LGPeWJNM._2Opt._2Opt();

            while (true)
            {
                try
                {
                    var meds = mc.Processar(instancia.Destinos, instancia.QuantidadeVeiculos, instancia.CapacidadeVeiculo);
                    var cluster = gj.Processar(meds, instancia.Destinos, instancia.Deposito, instancia.CapacidadeVeiculo);
                    var rota = vmp.Processar(cluster, instancia.Deposito, instancia.QuantidadeVeiculos, instancia.CapacidadeVeiculo);
                    var melhorado = opt.Processar(rota, instancia.Deposito, instancia.QuantidadeVeiculos, instancia.CapacidadeVeiculo);
                    if (totalOtimo > melhorado.CustoTotal())
                    {
                        totalOtimo = melhorado.CustoTotal();
                        otimo = melhorado;
                    }
                }
                catch (ArgumentOutOfRangeException)
                {
                    continue;
                }
            }
        }
    }
}
